﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.Storage;
using DBStoreWorkerRole.Contracts;
using DBStoreWorkerRole.Operations;

namespace DBStoreWorkerRole
{
    public class WorkerRole : RoleEntryPoint
    {
        // The name of your queue
        const string TopicName = "TemperatureDataLog";
        const string SubscriptionName1 = "DBSubscription";
        TempDBStoreProcessing dbop = new TempDBStoreProcessing();

        // QueueClient is thread-safe. Recommended that you cache 
        // rather than recreating it on every request
        SubscriptionClient Client;
        bool IsStopped;

        public override void Run()
        {
            while (!IsStopped)
            {
                try
                {
                    // Receive the message
                    BrokeredMessage receivedMessage = null;
                    receivedMessage = Client.Receive();

                    if (receivedMessage != null)
                    {                       
                        // Process the message
                        Trace.WriteLine("DBProcessing", receivedMessage.SequenceNumber.ToString());
                        try
                        {
                            switch (receivedMessage.Properties["UseCase"].ToString())
                            {
                                case "One":
                                    System.Diagnostics.Trace.WriteLine("Calling DataLogging");
                                    dbop.dataLogging_BL(receivedMessage.GetBody<TempDataLog>());
                                    break;
                                case "Two":
                                    System.Diagnostics.Trace.WriteLine("Calling GenericDataLogging");
                                    dbop.StoreData_BL(receivedMessage.GetBody<String>(), Convert.ToInt32(receivedMessage.Properties["deviceId"]), Convert.ToInt32(receivedMessage.Properties["sensorId"]));
                                    break;

                                default:
                                    break;
                            }
                        }
                        catch (Exception ex)
                        {

                        }
                        
                        receivedMessage.Complete();
                    }
                }
                catch (MessagingException e)
                {
                    if (!e.IsTransient)
                    {
                        Trace.WriteLine(e.Message);
                        //throw;
                    }

                    Thread.Sleep(1000);
                }
                catch (OperationCanceledException e)
                {
                    if (!IsStopped)
                    {
                        Trace.WriteLine(e.Message);
                        throw;
                    }
                }
            }
        }

        public override bool OnStart()
        {


            // To enable the AzureLocalStorageTraceListner, uncomment relevent section in the web.config  
            DiagnosticMonitorConfiguration diagnosticConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
            diagnosticConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
            diagnosticConfig.Directories.DataSources.Add(DBAzureLocalStorageTraceListener.GetLogDirectory());

            #region Diagnostics configuration

            // Get the default initial configuration for DiagnosticMonitor.
            DiagnosticMonitorConfiguration diagnosticConfiguration = DiagnosticMonitor.GetDefaultInitialConfiguration();


            // Create a custom logging path for crash dumps.
            string customCrashDumpsPath = RoleEnvironment.GetLocalResource("MyCustomCrashDumpsLocation").RootPath;


            // Enable full crash dump collection to the custom path. Pass in false
            // to enable mini crash dump collection. 
            CrashDumps.EnableCollectionToDirectory(customCrashDumpsPath, true);


            // Create a new DirectoryConfiguration object.
            DirectoryConfiguration directoryConfiguration = new DirectoryConfiguration();


            // Add the name for the blob container in Windows Azure storage.
            directoryConfiguration.Container = "wad-crash-dumps";


            // Add the directory size quota.
            directoryConfiguration.DirectoryQuotaInMB = RoleEnvironment.GetLocalResource("MyCustomCrashDumpsLocation").MaximumSizeInMegabytes;


            // Add the crash dumps path.
            directoryConfiguration.Path = customCrashDumpsPath;


            // Schedule a transfer period of 30 minutes.
            diagnosticConfiguration.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(30.0);


            // Add the directoryConfiguration to the Directories collection.
            diagnosticConfiguration.Directories.DataSources.Add(directoryConfiguration);


            // Start the DiagnosticMonitor using the diagnosticConfig and our connection string.
            DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diagnosticConfiguration);

            #endregion


            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            // Create the queue if it does not exist already
            string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
            try
            {
                //Create the Topic
                if (!namespaceManager.TopicExists(TopicName))
                {
                    namespaceManager.CreateTopic(TopicName);
                } 
           
                //Create subscriptions for the topic
                if (!namespaceManager.SubscriptionExists(TopicName, SubscriptionName1))
                {
                    
                    namespaceManager.CreateSubscription(TopicName, SubscriptionName1, new SqlFilter("StoreAction = 'Store'"));
                }
              
              
            }
            catch (MessagingException e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
            // Initialize the connection to Service Bus Queue

            // Creates the subscription client
            Client = SubscriptionClient.CreateFromConnectionString(connectionString, TopicName, SubscriptionName1);
            IsStopped = false;
            return base.OnStart();
        }

        public override void OnStop()
        {
            // Close the connection to Service Bus Queue
            IsStopped = true;
            Client.Close();
            base.OnStop();
        }
    }
}
